#include "application.h"


void Application::on_cleanup()
{
    m_Tab->Destroy();
    m_Session->Release();
    m_Core->Shutdown();

    SDL_DestroyTexture(m_ScreenTexture);
    SDL_DestroyRenderer(m_Renderer);
    SDL_DestroyWindow(m_Window);

    SDL_Quit();
}
void Application::on_close()
{
    TL::String cookie_str(512);
    char temp_str[512];
    JSValue js_value = m_Tab->ExecuteJavascriptWithResult(WSLit("document.cookie;"), WSLit(""));

    js_value.ToString().ToUTF8(temp_str, 512);

    cookie_str = temp_str;

    std::ofstream file("cookie.txt", std::ofstream::out);

    if (file.good()) {
        int steamLogin_start = cookie_str.FindFirstSubstringEnd("steamLogin=");
        int steamLogin_end = cookie_str.FindFirstSubstringEnd(";", steamLogin_start + 1);

        if (steamLogin_start != -1 && steamLogin_end != -1) {
            file << cookie_str.GetSubstring(steamLogin_end - steamLogin_start - 1, steamLogin_start + 1).GetCharString() << std::endl;
        } else{
            SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Warning", "Cookie can not be read. Probably, You did not perform login at Steam. File cookie.txt is not ready.", m_Window);
        }
    }
    else {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Warning", "Error during opening cookie.txt. File is not ready.", m_Window);
    }

    file.close();
}
void Application::on_display()
{
    SDL_SetRenderDrawColor(m_Renderer, 0x8A, 0xCF, 0xFF, 0xFF);
    SDL_RenderClear(m_Renderer);

    BitmapSurface *surface = (BitmapSurface *)m_Tab->surface();

    if (surface) {
        SDL_UpdateTexture(m_ScreenTexture, 0, surface->buffer(), surface->row_span());
        SDL_RenderCopy(m_Renderer, m_ScreenTexture, 0, 0);
    }

    SDL_RenderPresent(m_Renderer);
}
void Application::on_event(const SDL_Event &target_event)
{
    switch (target_event.type) {
    case SDL_MOUSEBUTTONDOWN:
        if (target_event.button.button == 1) {
            m_Tab->InjectMouseDown(MouseButton::kMouseButton_Left);
        }
        else if (target_event.button.button == 2) {
            m_Tab->InjectMouseDown(MouseButton::kMouseButton_Middle);
        }
        break;

    case SDL_MOUSEBUTTONUP:
        if (target_event.button.button == 1) {
            m_Tab->InjectMouseUp(MouseButton::kMouseButton_Left);
        }
        else if (target_event.button.button == 2) {
            m_Tab->InjectMouseUp(MouseButton::kMouseButton_Middle);
        }
        break;

    case SDL_MOUSEMOTION:
        m_Tab->InjectMouseMove(target_event.motion.x, target_event.motion.y);
        break;

    case SDL_MOUSEWHEEL:
        m_Tab->InjectMouseWheel(target_event.wheel.y * 40, target_event.wheel.x * 40);
        break;

    case SDL_TEXTINPUT:
        handleCharInput(m_Tab, target_event);
        break;

    case SDL_QUIT:
        m_Running = false;
        break;
    }
}
void Application::on_init()
{
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can not initialize SDL.", m_Window);
        return;
    }

    m_Window = SDL_CreateWindow("Steam Bot :: Browser", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_Width, m_Height, SDL_WINDOW_SHOWN);

    if (!m_Window) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can not create application window.", m_Window);
        return;
    }

    m_Renderer = SDL_CreateRenderer(m_Window, -1, SDL_RENDERER_ACCELERATED);

    if (!m_Renderer) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can not create application renderer.", m_Window);
        return;
    }

    m_ScreenTexture = SDL_CreateTexture(m_Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, m_Width, m_Height);

    if (!m_ScreenTexture) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can not create a texture.", m_Window);
        return;
    }

    m_Core = WebCore::Initialize(WebConfig());

    if (!m_Core || !m_Core->instance()) {
        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Can not initialize Awesomium.", m_Window);
        return;
    }

    m_Session = m_Core->CreateWebSession(WSLit("data"), WebPreferences());
    m_Tab = m_Core->CreateWebView(m_Width, m_Height, m_Session, kWebViewType_Offscreen);
}
void Application::on_start()
{
    m_Running = true;

    m_Tab->LoadURL(WebURL(WSLit("https://steamcommunity.com/market/?l=english")));
}
void Application::on_update()
{
    if (!m_Running) {
        return;
    }
    
    if (m_Core && m_Core->instance()) {
        m_Core->Update();
    }
}

Application::Application(int &argc, char **argv)
{
    m_Renderer = 0;
    m_ScreenTexture = 0;
    m_Window = 0;

    m_Core = 0;
    m_Session = 0;
    m_Tab = 0;

    // pre initialization
    m_Running = false;
    m_Width = 1280;
    m_Height = 720;
}
Application::~Application()
{
}

int Application::Execute()
{
    on_init();
    on_start();

    SDL_Event _event;

    while (m_Running) {
        while (SDL_PollEvent(&_event)) {
            on_event(_event);
        }

        on_display();
        on_update();

        SDL_Delay(1000 / 30);
    }

    on_close();
    on_cleanup();

    return 0;
}

void handleCharInput(WebView *web_view, const SDL_Event &target_event)
{
    WebKeyboardEvent keyEvent;

    keyEvent.type = WebKeyboardEvent::kTypeChar;

    keyEvent.text[0] = target_event.text.text[0];
    keyEvent.text[1] = target_event.text.text[1];
    keyEvent.text[2] = target_event.text.text[2];
    keyEvent.text[3] = target_event.text.text[3];

    web_view->InjectKeyboardEvent(keyEvent);
}
